14.2.4 管理应用

Stack是一组相关联的服务和基础设施,需要进行统一的部署和管理。虽然这句话里充斥着术语,但仍提醒我们Stack是由普通的Docker资源构建而来:网络、卷、密钥、服务等。这意味着可以通过普通的Docker命令对其进行查看和重新配置,例如 docker networkdocker volumedocker secretdocker service 等。

在此前提之下,通过 docker service 命令来管理Stack中某个服务是可行的。一个简单的例子是通过 docker service scale 命令来扩充 appserver 服务的副本数。但是,这并不是推荐的方式!

推荐方式是通过声明式方式修改,即将Stack文件作为配置的唯一声明。这样,所有Stack相关的改动都需要体现在Stack文件中,然后更新重新部署应用所需的Stack文件。

下面是一个简单例子,阐述了为什么通过命令修改的方式不好(通过CLI进行变更)。

假设读者已经部署了一个Stack,采用的Stack文件是前面章节中从GitHub复制的仓库中的 docker-stack.yml 。这意味着目前appserver服务有两个副本。如果通过 docker service scale 命令将副本修改为4个,当前运行的集群会有4个副本,但是Stack文件中仍然是两个。得承认目前看起来还不是特别糟糕。但是,假设读者又通过修改Stack文件对Stack做了某些改动,然后通过 docker stack deploy 命令进行滚动部署。这会导致 appserver 服务副本数被回滚到两个,因为Stack文件就是这么定义的。因此,推荐对Stack所有的变更都通过修改Stack文件来进行,并且将该文件放到一个合适的版本控制系统当中。

一起来回顾对Stack进行两个声明式修改的过程。目标是进行如下改动。

  • 增加 appserver 副本数,数量为2~10。
  • visualizer 服务的优雅停止时间增加到2min。

修改docker-stack.yml文件,更新两个值: services.appserver.deploy.replicas=10services.visualizer.stop_grace_period=2m

目前,Stack文件中的内容如下。

<Snip>
appserver:
  image: dockersamples/atsea_app
  networks:
    - front-tier
    - back-tier
    - payment
  deploy:
    replicas: 10             <<Updated value
<Snip>
visualizer:
  image: dockersamples/visualizer:stable
  ports:
    - "8001:8080"
stop_grace_period: 2m        <<Updated value
<Snip

保存文件并重新部署应用。

$ docker stack deploy -c docker-stack.yml seastack
Updating service seastack_reverse_proxy (id: z4crmmrz7zi83o0721heohsku)
Updating service seastack_database (id: 3vvpkgunetxaatbvyqxfic115)
Updating service seastack_appserver (id: ljht639w33dhv0dmht1q6mueh)
Updating service seastack_visualizer (id: rbwoyuciglre01hsm5fviabjf)
Updating service seastack_payment_gateway (id: w4gsdxfnb5gofwtvmdiooqvxs)

以上重新部署应用的方式,只会更新存在变更的部分。

运行 docker stack ps 命令来确认 appserver 副本数量确实增加。

$ docker stack ps seastack
NAME                    NODE  DESIRED STATE CURRENT STATE
seastack_visualizer.1   mgr-1 Running       Running 1 second ago
seastack_visualizer.1   mgr-1 Shutdown      Shutdown 3 seconds ago
seastack_appserver.1    wrk-2 Running       Running 24 minutes ago
seastack_appserver.2    wrk-1 Running       Running 24 minutes ago
seastack_appserver.3    wrk-2 Running       Running 1 second ago
seastack_appserver.4    wrk-1 Running       Running 1 second ago
seastack_appserver.5    wrk-2 Running       Running 1 second ago
seastack_appserver.6    wrk-1 Running       Starting 7 seconds ago
seastack_appserver.7    wrk-2 Running       Running 1 second ago
seastack_appserver.8    wrk-1 Running       Starting 7 seconds ago
seastack_appserver.9    wrk-2 Running       Running 1 second ago
seastack_appserver.10   wrk-1 Running       Starting 7 seconds ago

为了本书的排版效果,输出内容有所裁剪,只展示了受变更影响的服务。

注意关于 visualizer 服务有两行内容。其中一行表示某个副本在3s前停止,另一行表示新副本已经运行了1s。这是因为刚才对 visualizer 服务作了修改,所以Swarm集群终止了正在运行的副本,并且启动了新的副本,新副本中更新了 stop_grace_period 的值。

还需要注意的是, appserver 服务目前拥有10个副本,但不同副本的“CURRENT STATE”一列状态并不相同:有些处于running状态,而有些仍在starting状态。

经过足够的时间,集群的状态会完成收敛,期望状态和当前状态就会保持一致。在那时,集群中实际部署和观察到的状态,就会跟Stack文件中定义的内容完全一致。这真是让人开心的事情。

所有应用/Stack都应采用该方式进行更新。 所有的变更都应该通过Stack文件进行声明,然后通过 docker stack deploy 进行部署

正确的删除某个Stack方式是通过 docker stack rm 命令。一定要谨慎!删除Stack不会进行二次确认。

$ docker stack rm seastack
Removing service seastack_appserver
Removing service seastack_database
Removing service seastack_payment_gateway
Removing service seastack_reverse_proxy
Removing service seastack_visualizer
Removing network seastack_front-tier
Removing network seastack_payment
Removing network seastack_default
Removing network seastack_back-tier

注意,网络和服务已经删除,但是密钥并没有。这是因为密钥是在Stack部署前就创建并存在了。在Stack最上层结构中定义的卷同样不会被 docker stack rm 命令删除。这是因为卷的设计初衷是保存持久化数据,其生命周期独立于容器、服务以及Stack之外。

恭喜!读者现在学会了如何通过Docker Stack部署和管理一个多服务应用。

results matching ""

    No results matching ""